﻿using NewDevice;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace IP20.Procdure
{
    public class AsciiSerialPort : IDisposable
    {
        private readonly SerialPort _serialPort;
        private readonly object _lock = new object();

        /// <summary>
        /// 初始化串口通信类
        /// </summary>
        /// <param name="portName">串口号（如 COM1）</param>
        /// <param name="baudRate">波特率（默认9600）</param>
        /// <param name="parity">校验位（默认无校验）</param>
        /// <param name="dataBits">数据位（默认8位）</param>
        /// <param name="stopBits">停止位（默认1位）</param>
        public AsciiSerialPort(
            string portName,
            int baudRate = 9600,
            Parity parity = Parity.None,
            int dataBits = 8,
            StopBits stopBits = StopBits.One)
        {
            _serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits)
            {
                Encoding = Encoding.ASCII,
                ReadTimeout = 500,  // 500ms 读取超时
                WriteTimeout = 500   // 500ms 写入超时
            };
        }

        /// <summary>
        /// 打开串口连接
        /// </summary>
        public void Open()
        {
            lock (_lock)
            {
                if (!_serialPort.IsOpen)
                {
                    try
                    {
                        _serialPort.Open();
                    }
                    catch (UnauthorizedAccessException ex)
                    {
                        throw new InvalidOperationException("串口访问被拒绝（可能已被占用）", ex);
                    }
                    catch (IOException ex)
                    {
                        throw new InvalidOperationException("串口IO错误", ex);
                    }
                    catch (ArgumentException ex)
                    {
                        throw new InvalidOperationException("无效的串口参数", ex);
                    }
                }
            }
        }

        /// <summary>
        /// 发送 ASCII 字符串
        /// </summary>
        /// <param name="text">要发送的字符串</param>
        public void SendAsciiString(string text)
        {
            lock (_lock)
            {
                if (!_serialPort.IsOpen)
                    throw new InvalidOperationException("串口未打开");

                try
                {
                    // 将字符串转换为ASCII字节数组
                    byte[] asciiBytes = Encoding.ASCII.GetBytes(text);

                    // 发送数据
                    _serialPort.Write(asciiBytes, 0, asciiBytes.Length);
                }
                catch (TimeoutException)
                {
                    throw new TimeoutException("发送操作超时");
                }
                catch (InvalidOperationException ex)
                {
                    throw new InvalidOperationException("串口状态无效", ex);
                }
            }
        }

        /// <summary>
        /// 读取缓冲区中的 ASCII 字符串
        /// </summary>
        /// <param name="timeout">读取超时时间（毫秒）</param>
        /// <returns>读取到的ASCII字符串</returns>
        public string ReadExistingAsciiString(int timeout = 500)
        {
            lock (_lock)
            {
                if (!_serialPort.IsOpen)
                    throw new InvalidOperationException("串口未打开");

                try
                {
                    // 保存原始超时设置
                    int originalTimeout = _serialPort.ReadTimeout;

                    // 设置本次读取超时
                    _serialPort.ReadTimeout = timeout;

                    // 读取缓冲区所有可用数据[8](@ref)
                    string receivedData = _serialPort.ReadExisting();

                    // 恢复原始超时设置
                    _serialPort.ReadTimeout = originalTimeout;

                    return receivedData;
                }
                catch (TimeoutException)
                {
                    return string.Empty; // 超时返回空字符串
                }
                catch (InvalidOperationException ex)
                {
                    throw new InvalidOperationException("串口状态无效", ex);
                }
            }
        }

        /// <summary>
        /// 关闭串口连接
        /// </summary>
        public void Close()
        {
            lock (_lock)
            {
                if (_serialPort.IsOpen)
                {
                    _serialPort.Close();
                }
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            lock (_lock)
            {
                if (_serialPort != null)
                {
                    Close();
                    _serialPort.Dispose();
                }
            }
            GC.SuppressFinalize(this);
        }
    }
}